type 'a t = 'a list * 'a list

exception Out_of_bound
exception End_of_zip

let empty = [],[]

let next = function
    _, [] -> raise Out_of_bound
  | b, c::a -> c::b, a

let previous = function
    [], _ -> raise Out_of_bound
  | c::b, a -> b, c::a

let first (b,a) = ([], List.rev_append b a)

let last (b,a) = (List.rev_append a b, [])

let get = function
    _, [] -> raise End_of_zip
  | _, c::a -> c

let insert e (b,a)= (b,e::a)

let delete = function
    _, [] -> raise End_of_zip
  | b, c::a -> b,a

let replace e z = insert e (delete z)

let rev (b,a) = (a,b)

let append (b,a) (b',a') = (b, a@(List.rev_append b' a'))

let iter f = function
    b, a -> List.iter f (List.rev_append b a)

let chop = function b,a -> b, []

let from_list l = ([],l)

let to_list (b,a) = List.rev_append b a

let length z = List.length (to_list z)
